Imports ccapps.persistent.FTP
Imports ccapps.persistent.Telnet
Imports ccapps.persistent.Telnet.Scripting
Imports ccapps.persistent.DataLoad.ConfigurationProviders

Namespace persistent.DataLoad

    Public Class SimpleDataLoader
        Protected _ConfigurationProvider As ISimpleDataloadConfigurationProvider
        Protected _InputStream As System.IO.Stream
        Protected _StreamReader As System.IO.StreamReader
        Protected _EncodingConversationRequired As Boolean = False
        Protected _StreamWriter As System.IO.StreamWriter
        Protected _BulkDataOutputStream As System.IO.MemoryStream

        Protected Overridable Function initialize() As ActionResult

            'If Not Me._BulkDataOutputStream Is Nothing Then
            '    Me._BulkDataOutputStream.Close()
            'End If

            'If (Me.InputStream Is Nothing OrElse Me.InputStream.Length = 0) AndAlso Not Me._StreamReader Is Nothing Then
            '    Me._StreamReader.Close()
            'End If

            'If Not Me._StreamWriter. Is Nothing Then
            '    Me._StreamWriter.Close()
            'End If


            If Me.InputStream Is Nothing OrElse Me.InputStream.Length = 0 Then
                Return New ActionResult(False, "No appropriate file or file content!")
            End If

            Me.InputStream.Position = 0

            'Dim binaryReader As System.IO.BinaryReader
            If Me.Configuration.InputEncoding Is Nothing Then
                Me._StreamReader = New System.IO.StreamReader(Me.InputStream)
                'binaryReader = New System.IO.BinaryReader(Me.InputStream)
            Else
                Me._StreamReader = New System.IO.StreamReader(Me.InputStream, Me.Configuration.InputEncoding)
                'binaryReader = New System.IO.BinaryReader(Me.InputStream, Me.Configuration.InputEncoding)
            End If

            Me._BulkDataOutputStream = New System.IO.MemoryStream
            If Me.Configuration.OutputEncoding Is Nothing Then
                Me._StreamWriter = New System.IO.StreamWriter(Me._BulkDataOutputStream)
            Else
                Me._StreamWriter = New System.IO.StreamWriter(Me._BulkDataOutputStream, Me.Configuration.OutputEncoding)
            End If

            Return New ActionResult(True, String.Empty)
        End Function

        Protected Function readNextLineFromInput(ByRef lineContent As String) As Boolean

            If Me._StreamReader.Peek() = -1 Then
                lineContent = String.Empty
                Return False
            End If

            If _
            Not _
            ( _
                Me._StreamReader.CurrentEncoding Is Nothing OrElse _
                Me._StreamWriter.Encoding Is Nothing OrElse _
                Me._StreamReader.CurrentEncoding Is Me._StreamWriter.Encoding _
            ) _
            Then

                lineContent = Globals.ConvertEncoding(Me._StreamReader.ReadLine(), Me._StreamReader.CurrentEncoding, Me._StreamWriter.Encoding)

            Else
                lineContent = Me._StreamReader.ReadLine()

            End If

            Return True
        End Function

        Protected Overridable Function CheckInput() As ActionResult
            Dim initResult As ActionResult = Me.initialize()
            If Not initResult.IsSuccess Then
                Return New ActionResult(False, "Initialization failed!", Nothing, initResult)
            End If

            Dim line As String, lineIndex As Integer = -1

            Try

                While Me.readNextLineFromInput(line)
                    lineIndex += 1

                    If Me.Configuration.LineCountToRead > -1 AndAlso lineIndex >= Me.Configuration.StartLineIndex + Me.Configuration.LineCountToRead Then
                        Exit While
                    End If

                    If lineIndex >= Me.Configuration.StartLineIndex Then

                        If Not line.Trim().Length = 0 Then

                            If Not System.Text.RegularExpressions.Regex.IsMatch(line, Me.Configuration.DatalineValidationExpression) Then
                                Return New ActionResult(False, String.Format("File contains inappropriate input at line :{0}. Input: {1}", lineIndex + 1, line))
                            End If

                        End If

                    End If

                End While

                Return New ActionResult(True, String.Empty)

            Catch ex As Exception
                Return New ActionResult(False, String.Format("Error while reading the file! Line :{0}. Input: {1}", lineIndex + 1, line), innerResult:=New ActionResult(False, ex.Message))

            Finally

            End Try

        End Function

        Protected Overridable Function PrepareDataFile() As ActionResult
            Dim initResult As ActionResult = Me.initialize()
            If Not initResult.IsSuccess Then
                Return New ActionResult(False, "Initialization failed!", Nothing, initResult)
            End If

            Dim line As String, lineIndex As Integer = -1, dataParts() As String

            Try

                Dim _convertedDatafileHeader As String = Globals.ConvertEncoding(Me.Configuration.DataFileHeader, System.Text.Encoding.Default, Me._StreamWriter.Encoding)
                Me._StreamWriter.WriteLine _
                ( _
                    _convertedDatafileHeader _
                )

                While Me.readNextLineFromInput(line)
                    lineIndex += 1

                    If Me.Configuration.LineCountToRead > -1 AndAlso lineIndex >= Me.Configuration.StartLineIndex + Me.Configuration.LineCountToRead Then
                        Exit While
                    End If

                    If lineIndex >= Me.Configuration.StartLineIndex Then

                        If Not line.Trim().Length = 0 Then
                            dataParts = line.Split(Me.Configuration.DataPartSeperator)

                            'ReDim Preserve dataParts(dataParts.Length)

                            'Array.Copy(New String() {lineIndex}, 0, dataParts, dataParts.Length - 1, 1)

                            Me._StreamWriter.WriteLine _
                            ( _
                                String.Format _
                                ( _
                                    Me.Configuration.DataLineTemplate, dataParts _
                                ) _
                            )

                        End If

                    End If

                End While

                Return New ActionResult(True, String.Empty, Me._BulkDataOutputStream, Nothing)

            Catch ex As Exception
                Return New ActionResult(False, String.Format("Error while reading the file! Line :{0}. Input: {1}", lineIndex + 1, line), innerResult:=New ActionResult(False, ex.Message))

            Finally

            End Try

        End Function



        Public Shared Function LoadData(ByVal moduleName As String, ByVal fileID As String, ByVal content As String, ByVal encoding As System.Text.Encoding) As ActionResult

            Dim currentCulture As System.Globalization.CultureInfo = System.Globalization.CultureInfo.CurrentCulture

            Try

                System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.CreateSpecificCulture("en-US")

                Dim fileName As String = moduleName.Trim().ToLower() & "_" & fileID & "_input.dat"

                Dim actionResult1 As ActionResult = FTPUtility.UploadFile(GenericDataLoader.UnixGenericUploadPath, fileName, content, encoding)
                If Not actionResult1.IsSuccess Then
                    Return New ActionResult(False, "FTP failed!", Nothing, actionResult1)
                End If



                actionResult1 = TelnetUtility.LoadDataBySQLLoader(GenericDataLoader.UnixGenericUploadPath & fileName, GenericDataLoader.UnixGenericLogPath)
                If Not actionResult1.IsSuccess Then
                    Return New ActionResult(False, "Telnet failed!", Nothing, actionResult1)
                Else
                    Return New ActionResult(True, String.Empty)
                End If

            Catch ex As Exception
                Return New ActionResult(False, ex.Message)

            Finally

                System.Threading.Thread.CurrentThread.CurrentCulture = currentCulture

            End Try

        End Function


        Public Overridable Function Run() As ActionResult

            Dim inputCheckResult As ActionResult = Me.CheckInput()
            If inputCheckResult.IsSuccess Then

                Dim dataFilePrepareResult As ActionResult = Me.PrepareDataFile()
                If dataFilePrepareResult.IsSuccess Then


                    If Me.Configuration.RunningMode = DataLoadRunningModes.Real Then

                        Dim requestDetailCreateResult As ActionResult = Me.LoadData(Me.Configuration.ModuleName, Me.generateFileID(), GetStreamContent(CType(dataFilePrepareResult.AnyHookedObject, System.IO.Stream), Me._StreamWriter.Encoding), Me._StreamWriter.Encoding)
                        If requestDetailCreateResult.IsSuccess Then
                            Return New ActionResult(True, String.Empty)

                        Else
                            Return New ActionResult(False, "Request detail create failed!", Nothing, requestDetailCreateResult)

                        End If

                    Else
                        Return New ActionResult(True, String.Empty, dataFilePrepareResult.AnyHookedObject)

                    End If


                Else
                    Return New ActionResult(False, "Data file prepare failed!", Nothing, dataFilePrepareResult)

                End If

            Else
                Return New ActionResult(False, "Input check failed!", Nothing, inputCheckResult)

            End If

        End Function

        Protected Function generateFileID() As String
            Return System.Web.HttpContext.Current.Session("user") & "_" & DateTime.Now.ToString("yyyyMMddHHmmss")
        End Function


        'Public Shared ReadOnly Property UnixGenericUploadDirectoryName() As String
        '    Get
        '        Return UnixGenericUploadPath.Substring(UnixGenericUploadPath.LastIndexOf("/") + 1)
        '    End Get
        'End Property

        'Public Shared ReadOnly Property UnixGenericUploadPath() As String
        '    Get
        '        Return "/bscs/bscsadm/charging/crontab/input/billingnet_common/"
        '    End Get
        'End Property

        'Public Shared ReadOnly Property UnixGenericLogPath() As String
        '    Get
        '        Return "/bscs/bscsadm/charging/crontab/log/billingnet_common/"
        '    End Get
        'End Property



        Public ReadOnly Property Configuration() As ISimpleDataloadConfigurationProvider
            Get
                Return Me._ConfigurationProvider
            End Get
        End Property

        Public ReadOnly Property InputStream() As System.IO.Stream
            Get
                Return Me._InputStream
            End Get
        End Property

        Public Sub New(ByVal configurationProvider As ISimpleDataloadConfigurationProvider, ByVal inputStream As System.IO.Stream)
            Me._ConfigurationProvider = configurationProvider
            Me._InputStream = inputStream
        End Sub

    End Class

End Namespace
